home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / Messaging / MssgIntf.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-13  |  57.0 KB  |  1,850 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        MssgIntf.cpp
  3.  
  4.     Contains:    Implementation of ODMessageInterface class
  5.  
  6.     Owned by:    Nick Pilch
  7.  
  8.     Copyright:    © 1994 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <11>      12/13/96    JP        1607652: Added & disabled debugging code
  13.         <10>     9/23/96    JP        1384958: Replaced subject with token &
  14.                                     removed SEPriv.h include
  15.          <9>     6/20/96    JP        1328337: refcount predispatch handlers
  16.          <8>     5/24/96    jpa        1246074: SOM_CATCH --> SOM_TRY..SOM_ENDTRY
  17.          <6>    .03.1996    NP        Added comments about checking for the
  18.                                     current process.
  19.          <5>     3/14/96    TJ        Changed volatile to ODVolatile.
  20.          <4>      3/1/96    JP        1321991: Fixed potential memory leak
  21.          <3>     1/15/96    TJ        Cleaned Up
  22.          <2>      1/5/96    JP        1308887: Fixed aete handling
  23.  
  24.     To Do:
  25.         Check all functions and methods that call methods that *now* return ev
  26.         parameters.
  27.     In Progress:
  28.         
  29. */
  30.  
  31.  
  32. #ifndef _SIHELPER_
  33. #include "SIHelper.h"
  34. #endif
  35.  
  36. #ifndef _DFLTACS_
  37. #include <DfltAcs.h>
  38. #endif
  39.  
  40. #ifndef _BARRAY_
  41. #include "BArray.h"
  42. #endif
  43.  
  44. #ifndef _ORDCOLL_
  45. #include "OrdColl.h"
  46. #endif
  47.  
  48. #ifndef _EXCEPT_
  49. #include "Except.h"
  50. #endif
  51.  
  52. #ifndef _SEUTILS_
  53. #include "SEUtils.h"
  54. #endif
  55.  
  56. #ifndef _ODDESUTL_
  57. #include "ODDesUtl.h"
  58. #endif
  59.  
  60. #ifndef _ODMEMORY_
  61. #include "ODMemory.h"
  62. #endif
  63.  
  64. #ifndef SOM_ODNameSpaceManager_xh
  65. #include "NmSpcMg.xh"
  66. #endif
  67.  
  68. #ifndef _USERSRCM_
  69. #include <UseRsrcM.h>
  70. #endif
  71.  
  72. #ifndef SOM_ODSession_xh
  73. #include "ODSessn.xh"
  74. #endif
  75.  
  76. #ifndef SOM_ODPartWrapper_xh
  77. #include "PartWrap.xh"
  78. #endif
  79.  
  80. #ifndef SOM_ODNameResolver_xh
  81. #include "NamRslvr.xh"
  82. #endif
  83.  
  84. #ifndef SOM_ODSemanticInterface_xh
  85. #include "SemtIntB.xh"
  86. #endif
  87.  
  88. #ifndef SOM_DefaultAccessorSI_xh
  89. #include "MssgSI.xh"
  90. #endif
  91.  
  92. #ifndef SOM_ODAppleEvent_xh
  93. #include "ODAplEvt.xh"
  94. #endif
  95.  
  96. #ifndef SOM_ODObjectSpec_xh
  97. #include "ODObjSpc.xh"
  98. #endif
  99.  
  100. #ifndef SOM_ODAddressDesc_xh
  101. #include "ODAdrDes.xh"
  102. #endif
  103.  
  104. #ifndef _TEMPOBJ_
  105. #include <TempObj.h>
  106. #endif
  107.  
  108. #ifndef SOM_ODDesc_xh
  109. #include "ODDesc.xh"
  110. #endif
  111.  
  112. #ifndef SOM_ODOSLToken_xh
  113. #include "ODOSLTkn.xh"
  114. #endif
  115.  
  116. #ifndef _ODREGISTRY_
  117. #include "ODRgstry.xh"
  118. #endif
  119.  
  120. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  121. #include <StdDefs.xh>
  122. #endif
  123.  
  124. #ifndef __AEPACKOBJECT__
  125. #include <AEPackObject.h>
  126. #endif
  127.  
  128. #ifndef __AEOBJECTS__
  129. #include <AEObjects.h>
  130. #endif
  131.  
  132. #ifndef __ASREGISTRY__
  133. #include <ASRegistry.h>
  134. #endif
  135.  
  136. #ifndef __OSA__
  137. #include <OSA.h>
  138. #endif
  139.  
  140. #ifndef _ODDEBUG_
  141. #include "ODDebug.h"
  142. #endif
  143.  
  144. #define VARIABLE_MACROS
  145. #define ODMessageInterface_Class_Source
  146. #include <MssgIntf.xih>
  147.  
  148. #pragma segment ODMessageInterface
  149.  
  150. #include "MssgIntB.cpp"    // Platform-independent methods, if any
  151.  
  152. //#undef LOGGING
  153. //#define LOGGING 1
  154.  
  155. //==============================================================================
  156. // Globals defined
  157. //==============================================================================
  158.  
  159. ODMessageInterface*    gMessageInterface = kODNULL;
  160.  
  161. //==============================================================================
  162. // Local Classes
  163. //==============================================================================
  164.  
  165. class SETransactionLink : public Link
  166. {
  167.   public:
  168.     SETransactionLink(ODPart* part, ODSShort returnID)
  169.                             {fPart = part; fReturnID = returnID;}
  170.     ~  SETransactionLink() {}
  171.     
  172.     ODPart*    fPart;
  173.     ODSShort    fReturnID;
  174. };
  175.  
  176. class SETransactionList
  177. {
  178.   public:
  179.     void        Add(ODPart* part, ODSShort returnID);
  180.     void        Remove(ODPart* part, ODSShort returnID);
  181.     ODBoolean    Find(ODSShort returnID, ODPart** part);
  182.                     // returns kODFalse if not found.
  183. //    void        DeleteAll();
  184.  
  185.     ~SETransactionList();
  186.   private:
  187.     LinkedList    fList;
  188. };
  189.  
  190. struct PreHandlerInfo
  191. {
  192.   public:
  193.     PreHandlerInfo(ODSemanticInterface* face, ODULong refCon)
  194.                         {fSemanticInterface = face; fRefCon = refCon;}
  195.  
  196.     ODSemanticInterface*    GetSemanticInterface()
  197.                                     {return fSemanticInterface;}
  198.     ODULong                        GetRefCon() {return fRefCon;}
  199.   private:
  200.     ODSemanticInterface*    fSemanticInterface;
  201.     ODULong                        fRefCon;
  202. };
  203.  
  204. //==============================================================================
  205. // Function Prototype
  206. //==============================================================================
  207.  
  208. static ODSShort GetReturnID(AppleEvent* ae);
  209. static ODBoolean SentToSelf(AppleEvent* ae);
  210. static ODPart* GetTokenPart( Environment* ev, ODNameResolver* resolver,
  211.         AEDesc* token );
  212. static pascal OSErr HandleAllSEvents(    AppleEvent* message,
  213.                                         AppleEvent* reply,
  214.                                         long refCon);
  215. static pascal OSErr HandleReplies(    AppleEvent* message,
  216.                                     AppleEvent* reply,
  217.                                     long refCon);
  218. static pascal OSErr HandleGetAETE(    AppleEvent* message,
  219.                                     AppleEvent* reply,
  220.                                     long refCon);
  221. static pascal OSErr HandleAllCoercions(    const AEDesc*    theAEDesc,
  222.                                         DescType        toType,
  223.                                         long            refCon,
  224.                                         AEDesc*            retDesc);
  225. static pascal OSErr HandlePreDispatch(    AppleEvent* message,
  226.                                         AppleEvent* reply,
  227.                                         long refCon);
  228. static void PlaceEmptyListIntoReply(AppleEvent* reply);
  229. static void CreateSubjectObject(Environment* ev, ODFrame* frame, AEDesc* objSpec);
  230.  
  231.  
  232. //==============================================================================
  233. // SETransactionList
  234. //==============================================================================
  235.  
  236. //------------------------------------------------------------------------------
  237. // SETransactionList::Add
  238. //------------------------------------------------------------------------------
  239.  
  240. void SETransactionList::Add(ODPart* part, ODSShort returnID)
  241. {
  242.     SETransactionLink* aLink = new SETransactionLink(part, returnID);
  243.     if (!aLink)
  244.         THROW(kODErrOutOfMemory);
  245.     fList.AddLast(aLink);
  246. }
  247.  
  248. //------------------------------------------------------------------------------
  249. // SETransactionList::Remove
  250. //
  251. //    Do I really need to match both things? How about only the returnID?
  252. //------------------------------------------------------------------------------
  253.  
  254. void SETransactionList::Remove(ODPart* part, ODSShort returnID)
  255. {
  256.     LinkedListIterator iter(&fList);
  257.  
  258.     SETransactionLink* aLink = (SETransactionLink*)iter.First();
  259.     while (aLink != NULL)
  260.     {
  261.         if ((aLink->fPart == part) && (aLink->fReturnID) == returnID)
  262.         {
  263.             fList.Remove(*aLink);
  264.             delete aLink;
  265.             break;
  266.         }
  267.         else
  268.             aLink = (SETransactionLink*)iter.Next();
  269.     }
  270. }
  271.  
  272. //------------------------------------------------------------------------------
  273. // SETransactionList::Find
  274. //------------------------------------------------------------------------------
  275.  
  276. ODBoolean SETransactionList::Find(ODSShort returnID, ODPart** part)
  277. {
  278.     LinkedListIterator iter(&fList);
  279.  
  280.     SETransactionLink* aLink = (SETransactionLink*)iter.First();
  281.     while (aLink != NULL)
  282.     {
  283.         if (aLink->fReturnID == returnID)
  284.         {
  285.             *part = aLink->fPart;
  286.             return kODTrue;
  287.         }
  288.         else
  289.             aLink = (SETransactionLink*)iter.Next();
  290.     }
  291.     return kODFalse;
  292. }
  293.  
  294. //------------------------------------------------------------------------------
  295. // SETransactionList::DeleteAll (Copied from OrderedCollection::DeleteAll)
  296. //------------------------------------------------------------------------------
  297. // This is a no-op now that value isn't being deleted (which it never should
  298. // have been.)  So we just call the destructor instead.
  299. #if 0
  300. void SETransactionList::DeleteAll()
  301. {
  302.     Link* link;    // = fList.RemoveFirst();
  303.     while ((link = fList.RemoveFirst()) != kODNULL)
  304.     {
  305.         ElementType value = ((ValueLink*) link)->GetValue();
  306. //        delete value;        // <eeh> no value was allocated by Add.  This is
  307.                             // an ODPartWrapper* that may have a refcount > 0.
  308.                             // And if I'm right that we should not delete value,
  309.                             // then this whole method can be replaced with a call:
  310.                             // fList.DeleteAllLinks();
  311.         delete link;
  312. //        link = fList.RemoveFirst();
  313.     }
  314. }
  315. #endif
  316.  
  317. //------------------------------------------------------------------------------
  318. // SETransactionList::~SETransactionList
  319. //------------------------------------------------------------------------------
  320.  
  321. SETransactionList::~SETransactionList()
  322. {
  323.     fList.DeleteAllLinks();
  324. }
  325.  
  326. //==============================================================================
  327. // ODMessageInterface
  328. //==============================================================================
  329.  
  330. //------------------------------------------------------------------------------
  331. // ODMessageInterface::InitMessageInterface
  332. //------------------------------------------------------------------------------
  333.  
  334. SOM_Scope void  SOMLINK ODMessageInterfaceInitMessageInterface(ODMessageInterface *somSelf, Environment *ev,
  335.         ODSession* session)
  336. {
  337.     SOM_TRY
  338.  
  339.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  340.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceInitMessageInterface");
  341.  
  342.     /* Moved from somInit. SOM itself sets fields to zero
  343.     _fPreHandlers = kODNULL;
  344.     _fTransactionList = kODNULL;
  345.     _fSession = kODNULL;
  346.     _fNameResolver = kODNULL;
  347.     _fDefaultSI = kODNULL;
  348.     */
  349.     _fNextReturnID = 1;
  350.     somSelf->InitObject(ev);
  351.  
  352.     gMessageInterface = somSelf; // FOR THE PREHANDLER PROC THAT DOESN'T HAVE A
  353.                                  //    REFCON.
  354.  
  355.     _fSession = session;
  356.     _fNameResolver = _fSession->GetNameResolver(ev);
  357.     _fTransactionList = new SETransactionList;
  358.     _fPreHandlers = new OrderedCollection;
  359.  
  360.     DefaultAccessorSI* face = new DefaultAccessorSI();
  361. //    SIHelper* help = new SIHelper();
  362. //    help->InitSIHelper(face);
  363. //    face->InitCPlusSemanticInterface(ev, kODAppShell, help, _fSession);
  364.     face->InitCPlusSemanticInterface(ev, kODAppShell, kODNULL, _fSession);
  365.     _fDefaultSI = face;
  366.  
  367.     
  368.     THROW_IF_ERROR(AEInstallEventHandler(typeWildCard, typeWildCard,
  369.                     NewAEEventHandlerProc(HandleAllSEvents),
  370.                     (long)somSelf, ! kIsSysHandler));
  371.     
  372.     THROW_IF_ERROR(AEInstallEventHandler(kCoreEventClass, kAEAnswer,
  373.                     NewAEEventHandlerProc(HandleReplies),
  374.                     (long)somSelf, ! kIsSysHandler));
  375.     
  376.     THROW_IF_ERROR(AEInstallEventHandler(kASAppleScriptSuite, kGetAETE,
  377.                     NewAEEventHandlerProc(HandleGetAETE),
  378.                     (long)somSelf, ! kIsSysHandler));
  379.     
  380.     THROW_IF_ERROR(AEInstallSpecialHandler(keyPreDispatch,
  381.                     (UniversalProcPtr)NewAEEventHandlerProc(HandlePreDispatch),
  382.                     ! kIsSysHandler));
  383.     
  384.     THROW_IF_ERROR(AEInstallCoercionHandler(typeWildCard, typeWildCard,
  385.                     (AECoercionHandlerUPP)NewAECoerceDescProc(HandleAllCoercions),
  386.                     (long)somSelf, kFromTypeIsDesc, ! kIsSysHandler));
  387.  
  388.     SOM_CATCH_ALL
  389.     SOM_ENDTRY
  390. }
  391.  
  392. //------------------------------------------------------------------------------
  393. // ODMessageInterface::somUninit
  394. //------------------------------------------------------------------------------
  395.  
  396. SOM_Scope void  SOMLINK ODMessageInterfacesomUninit(ODMessageInterface *somSelf)
  397. {
  398.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  399.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfacesomUninit");
  400.  
  401.     Environment*     ev = somGetGlobalEnvironment ();
  402.  
  403.     ODDeleteObject( _fTransactionList );
  404.     
  405.     if (_fPreHandlers)
  406.     {
  407.         _fPreHandlers->DeleteAll();
  408.         ODDeleteObject( _fPreHandlers );
  409.     }
  410.     
  411.     ODReleaseObject(ev, _fDefaultSI);
  412. }
  413. #if 0
  414. //------------------------------------------------------------------------------
  415. // ODMessageInterface::Purge
  416. //------------------------------------------------------------------------------
  417.  
  418. SOM_Scope ODSize  SOMLINK ODMessageInterfacePurge(ODMessageInterface *somSelf, Environment *ev,
  419.         ODSize size)
  420. {
  421. //    ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  422.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfacePurge");
  423.  
  424.     ODSize purged = 0; ODVolatile( purged );
  425.  
  426.     SOM_TRY
  427.         purged = ODMessageInterface_parent_ODObject_Purge(somSelf,ev,size);
  428.     SOM_CATCH_ALL
  429.         WARN("Error %ld trying to purge in ODMessageInterfacePurge",ErrorCode());
  430.         SetErrorCode(kODNoError);        // Eat the exception; Purge should not 
  431.                                         // propagate it because clients function
  432.                                         // fine whether memory was purged or not.
  433.         // dh - Also removed zeroing of purge total if an exception was thrown.
  434.         // The number should be accurate regardless of exceptions because of
  435.         // the initializer of the counter.
  436.     SOM_ENDTRY
  437.     
  438.     return purged;
  439. }
  440. #endif /* 0 */
  441. //------------------------------------------------------------------------------
  442. // ODMessageInterface::CreateEvent
  443. //------------------------------------------------------------------------------
  444.  
  445. SOM_Scope ODSShort  SOMLINK ODMessageInterfaceCreateEvent(ODMessageInterface *somSelf, Environment *ev,
  446.         ODEventClass theAEEventClass,
  447.         ODEventID theAEEventID,
  448.         ODAddressDesc* target,
  449.         ODSLong transactionID,
  450.         ODAppleEvent** result)
  451. {
  452.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  453.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceCreateEvent");
  454.  
  455.     OSErr        error;
  456.     ODSShort    retVal = 0;
  457.  
  458.     SOM_TRY
  459.         // TO BE ABSOLUTELY CORRECT, I SHOULD CHECK THAT THE RETURN ID I'M USING IS
  460.         //    NOT IN THE _fTransactionList. HOWEVER, IS THIS OVERKILL? -- Yes.
  461.         AppleEvent        newEvent;
  462.     
  463.         AEAddressDesc    targetAsAEDesc;
  464.         error = ODDescToAEDesc( target, &targetAsAEDesc );
  465.     
  466.         if ( !error )
  467.         {
  468.             error = AECreateAppleEvent(theAEEventClass, theAEEventID,
  469.                                                 &targetAsAEDesc,
  470.                                                 _fNextReturnID, transactionID,
  471.                                                 &newEvent);
  472.             AEDisposeDesc(&targetAsAEDesc);
  473.         }
  474.     
  475.         if ( !error )
  476.         {    // stick it in the event
  477.             ODAppleEvent* coverEvent = new ODAppleEvent();
  478.             THROW_IF_NULL(coverEvent);
  479.             coverEvent->InitODAppleEvent(ev);
  480.             error = AEDescToODDesc( &newEvent, coverEvent );
  481.             ODDisposeAppleEvent(&newEvent);
  482.             if ( !error )
  483.                 *result = coverEvent;
  484.             else
  485.             {
  486.                 ODDeleteObject(coverEvent);
  487.                 *result = kODNULL;
  488.             }
  489.         }
  490.     
  491.         THROW_IF_ERROR (error);
  492.     
  493.         retVal = _fNextReturnID++;
  494.     SOM_CATCH_ALL
  495.     SOM_ENDTRY
  496.  
  497.     return retVal;
  498. }
  499.  
  500. //------------------------------------------------------------------------------
  501. // ODMessageInterface::Send
  502. //------------------------------------------------------------------------------
  503.  
  504. SOM_Scope void  SOMLINK ODMessageInterfaceSend(ODMessageInterface *somSelf, Environment *ev,
  505.         ODFrame* toFrame,
  506.         ODPart* fromPart,
  507.         ODAppleEvent* theAppleEvent,
  508.         ODAppleEvent* reply,
  509.         ODSendMode sendMode,
  510.         ODSendPriority sendPriority,
  511.         ODULong timeOutInTicks)
  512. {
  513.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  514.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceSend");
  515.  
  516.     // MIGHT CHECK WHETHER WE'RE SENDING IN THE SAME PROCESS. THEN WE CAN
  517.     //    AVOID THE APPLEEVENT MANAGER ALTOGETHER PERHAPS!!!!
  518.     AppleEvent                realEvent = NULL_DESCRIPTOR_DEFINITION;
  519.     AppleEvent                realReply = NULL_DESCRIPTOR_DEFINITION;
  520.     OSErr                    result;
  521.     ODSShort                returnID;
  522.     ODBoolean                isCurrentProcess;
  523.  
  524.     SOM_TRY
  525.         THROW_IF_ERROR( ODDescToAEDesc(theAppleEvent, &realEvent ));
  526. //        THROW_IF_ERROR( ODDescToAEDesc(reply, &realReply ));
  527.  
  528.         // add subject attribute
  529.         if (toFrame)
  530.         {
  531.             AEDesc    subj = NULL_DESCRIPTOR_DEFINITION;
  532.             CreateSubjectObject(ev, toFrame, &subj);
  533.             THROW_IF_ERROR( AEPutAttributeDesc(&realEvent, keySubjectAttr, &subj) );
  534.             AEDisposeDesc(&subj);
  535.         }
  536.     
  537.         TRY
  538.             returnID = GetReturnID(  &realEvent );
  539.         CATCH_ALL
  540.             returnID = _fNextReturnID++;
  541.         ENDTRY
  542.         _fTransactionList->Add(fromPart, returnID);
  543.  
  544.         // $$$$$ CURRENTLY, THIS DOES NOT RETURN THE CORRECT RESULT. THEREFORE,
  545.         //    THE "if" WILL ONLY BE ENTERED IF THE CALLING PART SPECIFIES
  546.         //    kCurrentProcess IN THE ADDRESS DESCRIPTOR AND kAEQueueReply. THERE
  547.         //    ARE NO TEST CASES FOR THIS THAT I KNOW OF, HOWEVER.
  548.         isCurrentProcess = SentToSelf( &realEvent );
  549.     
  550.         if ((sendMode == kAEQueueReply) && isCurrentProcess)
  551.         {
  552.             // WORK AROUND CONDITION THAT REPLY HANDLER IS NOT CALLED IF SENDING
  553.             //    IN THE SAME PROCESS. DO WE HAVE TO DO THIS? PEOPLE SHOULD ALREADY
  554.             //    EXPECT IT. MAYBE WE LET THE USUAL THING HAPPEN FOR A PART SENDING
  555.             //    TO ITSELF AND DO THE MAGIC IF THE SENDER AND RECEIVER PARTS ARE
  556.             //    DIFFERENT!!!!
  557.             result = AESend(&realEvent, &realReply,
  558.                             kAEWaitReply, sendPriority,
  559.                             timeOutInTicks, (AEIdleUPP)kODNULL,
  560.                             (AEFilterUPP)kODNULL);
  561.     
  562.             if (result == noErr)
  563.                     // <eeh> is this right?
  564.                     result = somSelf->DispatchToEventHandler(ev, &realReply,
  565.                             nil, fromPart, kODNULL);
  566.             _fTransactionList->Remove(fromPart, returnID);
  567.         }
  568.         else
  569.         {
  570.             result = AESend(&realEvent, &realReply,
  571.                             sendMode, sendPriority,
  572.                             timeOutInTicks, (AEIdleUPP)kODNULL,
  573.                             (AEFilterUPP)kODNULL);
  574.     
  575.             if ((sendMode & kAEWaitReply != 0)
  576.                         || (sendMode == kAENoReply)
  577.                         || (result != noErr))
  578.                 _fTransactionList->Remove(fromPart, returnID);
  579.         }
  580.     
  581.         //    UPDATE REPLY FOR CALLER
  582.         THROW_IF_ERROR(AEDescToODDesc(&realReply, reply));
  583. #ifdef TO_BE_DELETED
  584.         if (realReply.descriptorType != typeNull
  585.                 && realReply.dataHandle != kODNULL)
  586.         {
  587.             AEDesc    tempDesc;
  588.             OSErr    tempErr;
  589.             tempErr = AEGetParamDesc(&realReply, keyDirectObject, typeWildCard,
  590.                                         &tempDesc);
  591.             if (!tempErr)
  592.                 AEDisposeDesc(&tempDesc);
  593.         }
  594. #endif
  595.         THROW_IF_ERROR (result);
  596.     SOM_CATCH_ALL
  597.     SOM_ENDTRY
  598.  
  599.     ODDisposeAppleEvent(&realReply);
  600.     ODDisposeAppleEvent(&realEvent);
  601. }
  602.  
  603. //------------------------------------------------------------------------------
  604. // ODMessageInterface::ProcessSemanticEvent
  605. //------------------------------------------------------------------------------
  606.  
  607. SOM_Scope ODBoolean  SOMLINK ODMessageInterfaceProcessSemanticEvent(ODMessageInterface *somSelf, Environment *ev,
  608.         ODEventData* theEvent)
  609. {
  610. //    ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  611.     ODMessageInterfaceMethodDebug("ODMessageInterface","ProcessSemanticEvent");
  612.  
  613.     return ! AEProcessAppleEvent((const EventRecord*)theEvent);
  614. }
  615.  
  616. //------------------------------------------------------------------------------
  617. // HandleAllSEvents
  618. //------------------------------------------------------------------------------
  619.  
  620. static pascal OSErr HandleAllSEvents(AppleEvent* message,
  621.                                                         AppleEvent* reply,
  622.                                                         long refCon)
  623. {
  624.     ODMessageInterface* self = (ODMessageInterface*)refCon;
  625.  
  626.     return self->HandleAllSEventsAux(somGetGlobalEnvironment(),
  627.                                         message,
  628.                                         reply);
  629. }
  630.  
  631. //------------------------------------------------------------------------------
  632. // ODMessageInterface::HandleAllSEventsAux
  633. //
  634. //    If there's an object specifier in the direct parameter, we use it to find
  635. //    out to whom to send the event.
  636. //
  637. //    Rework flow of control!!!!
  638. //
  639. //    Since it's a private method, I'm not using SOM exceptions for now.
  640. //------------------------------------------------------------------------------
  641.  
  642. SOM_Scope OSErr  SOMLINK ODMessageInterfaceHandleAllSEventsAux(ODMessageInterface *somSelf, Environment *ev,
  643.         AppleEvent* message,
  644.         AppleEvent* reply)
  645. {
  646.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  647.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceHandleAllSEventsAux");
  648. //DebugStr("\pOK. Here we are.");
  649.  
  650.     OSErr                result;
  651.     AEDesc                theObject;
  652.     OSLToken            tokenAsAEDesc = NULL_DESCRIPTOR_DEFINITION;
  653.     ODBoolean            doResolution = kODFalse;
  654.     ODBoolean            gotSubject = kODFalse;
  655.     ODPart*                destinationPart = kODAppShell;
  656.     ODBoolean            haveValidObject = kODFalse;
  657.  
  658. #if ODDebug
  659.     // just so I can see what event I'm dealing with in the debugger
  660.     ODDescType            debugEventClass;
  661.     ODDescType            debugEventID;
  662.     ODSLong                debugSize;
  663.     ODDescType            debugType;
  664.     
  665.     AEGetAttributePtr(message, keyEventClassAttr,
  666.                                 typeType, &debugType, (Ptr)&debugEventClass,
  667.                                 sizeof(debugEventClass), &debugSize);
  668.     AEGetAttributePtr(message, keyEventIDAttr,
  669.                                 typeType, &debugType, (Ptr)&debugEventID,
  670.                                 sizeof(debugEventID), &debugSize);
  671.     LOG("event %4.4s%4.4s\n", &debugEventClass,  &debugEventID);
  672. #endif
  673.  
  674.         
  675.     // Reset these, because I might be examining them real soon.
  676. //    _fNameResolver->SetLastContainer(ev, typeNull);
  677. //    _fNameResolver->SetLastObject(ev, typeNull);
  678. //    _fNameResolver->ClearLastSwapFrame(ev) ;
  679. //DebugStr("\pStart event handler;ht;g");
  680.     TRY
  681.         _fNameResolver->NeedContextCache(ev, kODTrue);
  682.  
  683.         // SEE IF WE HAVE TO SPECIAL CASE THIS EVENT
  684. //        if (somSelf->HandleSpecialEvents(ev, message, reply, &result))
  685. //            return result;
  686.     
  687.         result = AEGetParamDesc(message, keyDirectObject,
  688.                                 typeWildCard,
  689.                                 &theObject);
  690.         if (!result)
  691.             haveValidObject = kODTrue;
  692.         // IF WE HAVE AN OBJECT SPECIFIER IN THE DIRECT OBJECT, USE IT TO FIND
  693.         //    PART TO DISPATCH TO.
  694.         // BUT CHECK FOR SPECIAL OBJECT SPECIFIER
  695.         if (!result && (theObject.descriptorType == typeObjectSpecifier))
  696.         {
  697.             DescType    gotType;
  698.             DescType    desiredPartSize = sizeof(ODPart*);
  699.             DescType    desiredDescSize = sizeof(DescType);
  700.             DescType    gotSize;
  701.             DescType    keyForm;
  702.             ODPart*    thePart;
  703.             AEDesc        objSpecCopy;
  704.             AEDesc        objSpecAsRecord;
  705.     
  706. //            DebugStr("\pgot it.");
  707.             // IS IT ONE OF OUR SPECIAL OBJECT SPECIFIERS?
  708.             THROW_IF_ERROR(AEDuplicateDesc(&theObject, &objSpecCopy));
  709.             result = AECoerceDesc(&objSpecCopy, typeAERecord, &objSpecAsRecord);
  710.             if (!result)
  711.             {
  712.                 result = AEGetKeyPtr(&objSpecAsRecord, keyAEKeyForm,
  713.                                         typeEnumerated, &gotType, &keyForm,
  714.                                         desiredDescSize, (long*)&gotSize);
  715.                 if (!result && (gotType == typeEnumerated)
  716.                         && (gotSize == desiredDescSize) && (keyForm == cPart))
  717.                 {
  718.                     result = AEGetKeyPtr(&objSpecAsRecord, keyAEKeyData,
  719.                                             typeLongInteger, &gotType, &thePart,
  720.                                             desiredPartSize, (long*)&gotSize);
  721.                     if (!result && (gotType == typeLongInteger)
  722.                             && (gotSize == desiredPartSize))
  723.                         destinationPart = thePart;
  724.                     else
  725.                         doResolution = kODTrue;
  726.                 }
  727.                 else
  728.                     doResolution = kODTrue;
  729.             }
  730.             else
  731.                 doResolution = kODTrue;
  732.     
  733.             AEDisposeDesc(&objSpecCopy);
  734.             AEDisposeDesc(&objSpecAsRecord);
  735.         }
  736.         else
  737.         {
  738.             // NO DIRECT OBJECT, BUT HAVE A SUBJECT ATTRIBUTE, USE IT TO FIND
  739.             //    PART TO DISPATCH TO.
  740.             AEDesc theSubject = NULL_DESCRIPTOR_DEFINITION;
  741.             result = AEGetAttributeDesc(message,
  742.                                         keySubjectAttr, typeWildCard,
  743.                                         &theSubject);
  744.     
  745.             if (!result && (theSubject.descriptorType == typeObjectSpecifier))
  746.             {
  747.                 theObject = theSubject;
  748.                 doResolution = kODTrue;
  749.                 gotSubject = kODTrue;
  750.                 haveValidObject = kODTrue;
  751.             }
  752.             else
  753.                 AEDisposeDesc(&theSubject);
  754.         }
  755.  
  756.         if (doResolution)
  757.         {
  758.             OSErr    error = noErr;
  759.             ODObjectSpec* objWrapper = new ODObjectSpec();
  760.             THROW_IF_NULL(objWrapper);
  761.             objWrapper->InitODObjectSpec(ev);
  762.             ODOSLToken* theToken = new ODOSLToken();
  763.             THROW_IF_NULL(theToken);
  764.             theToken->InitODOSLToken(ev);
  765.  
  766.             TRY
  767.                 THROW_IF_ERROR( AEDescToODDesc(&theObject, objWrapper ) );
  768.  
  769.                 theToken->SetDescType(ev, typeNull);
  770.                 
  771.                 _fNameResolver->Resolve(ev, objWrapper, theToken, kODAppShell);
  772. #if ODDebug
  773.                 if (_fNameResolver->IsODToken(ev, theToken)) {
  774.                     ODPart*        debugContextPart;
  775.                     ODFrame*    debugContextFrame;
  776.                     _fNameResolver->GetContextFromToken(ev, theToken, &debugContextPart, &debugContextFrame);
  777.                     LOG("!resolved context - part: %8.8x, frame: %8.8x\n", debugContextPart, debugContextFrame);
  778.                 }
  779. #endif
  780.                 THROW_IF_ERROR(ODDescToAEDesc(theToken, &tokenAsAEDesc));
  781.  
  782.             CATCH_ALL
  783.                 result = ErrorCode();
  784.             ENDTRY
  785.             ODDeleteObject( objWrapper );
  786.             if ( !result )
  787.             {
  788.                 result = somSelf->DispatchEventWithToken(ev, &tokenAsAEDesc,
  789.                         message, reply, gotSubject, kODFalse);
  790.                 // DispatchEventWithToken may have modified the token.  Copy
  791.                 // into the ODDesc that will be passed to DisposeToken.
  792.                 THROW_IF_ERROR( AEDescToODDesc( &tokenAsAEDesc, theToken ));
  793.                 AEDisposeDesc(&tokenAsAEDesc);
  794.             }
  795.             if (theToken)
  796.                 _fNameResolver->DisposeToken(ev, theToken);
  797.         }
  798.         else if ( theObject.descriptorType == typeUserToken )
  799.         {
  800.             result = somSelf->DispatchEventWithToken(ev, &theObject,
  801.                     message, reply, gotSubject, kODTrue );
  802.         }
  803.         else
  804.             // SEND TO THE DESTINATION DIRECTLY
  805.             result = somSelf->DispatchToEventHandler(ev, message, reply,
  806.                                             destinationPart, kODNULL );
  807.     CATCH_ALL
  808.         result = ErrorCode();
  809.         if (haveValidObject)
  810.             AEDisposeDesc(&theObject);
  811.     ENDTRY
  812.  
  813.     if (haveValidObject)
  814.         AEDisposeDesc(&theObject);
  815.  
  816.     _fNameResolver->NeedContextCache(ev, kODFalse);
  817.     _fNameResolver->FlushContextCache(ev);
  818. //DebugStr("\p with event handler;ht");
  819.     return result;
  820. }    // HandleAllSEventsAux
  821.  
  822. //------------------------------------------------------------------------------
  823. // ODMessageInterface::DispatchEventWithToken
  824. //
  825. //    Recursive routine to deal with list tokens whose items might be other
  826. //    lists. But should we stop dispatching if we get an error????
  827. //
  828. //    Need to clean up flow of control here.
  829. //
  830. //    Since it's a private method, I'm not using SOM exceptions for now.
  831. //------------------------------------------------------------------------------
  832.  
  833. SOM_Scope OSErr  SOMLINK ODMessageInterfaceDispatchEventWithToken(ODMessageInterface *somSelf, Environment *ev,
  834.         OSLToken* token,
  835.         AppleEvent* message,
  836.         AppleEvent* reply,
  837.         ODBoolean usingSubjectAttr,
  838.         ODBoolean dpAlreadyToken)
  839. {
  840.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  841.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceDispatchEventWithToken");
  842.  
  843.     OSErr        error = noErr;
  844.     ODBoolean    handledEventRightHere = kODFalse;
  845.     
  846.     // WE USED TO UNPACK ALL LISTS, EVEN THOSE CREATED BY A PART EDITOR. NOW
  847.     //    WE ONLY NEED TO DEAL WITH LISTS IF THE OSL CREATES THEM ITSELF.
  848.     //    UNFORTUNATELY, I'M NOT SURE WHAT THE RIGHT THING TO DO IS. IF WE UNPACK
  849.     //    THE  LIST AND MULTICAST OURSELVES, WE COULD END UP WITH MULTIPLE EVENTS
  850.     //    WHEN ONLY ONE WAS APPROPRIATE. NEED TO CONFER WITH KURT. -NP 5/19/95
  851.     if (token->descriptorType == typeAEList)
  852.     {
  853.         AEDesc        embeddedToken;
  854.         ODSLong        itemCount;
  855.         AEKeyword    returnedKeyWord;
  856.         ODFrame*    prevFrame;
  857.         ODFrame*    thisFrame;
  858.         ODPart*        prevPart;
  859.         ODPart*        thisPart;
  860.  
  861.         #if ODDebug
  862. //            ASSERTM(kODFalse, errAEEventNotHandled, "ODMessageInterfaceDispatchEventWithToken: Handling of lists returned by OSL not yet implemented.");
  863.         #else        
  864. //            DebugStr("\pHandling of lists returned by OSL not yet implemented.");
  865. //            THROW(errAEEventNotHandled);
  866.         #endif
  867.         THROW_IF_ERROR(AECountItems(token, &itemCount));
  868.  
  869.         // I THINK ALL THE TOKENS IN THE LIST SHOULD HAVE BEEN CREATED IN THE
  870.         //    SAME CONTEXT. FOR NOW, I JUST WANT TO VERIFY THIS IS SO AND RAISE
  871.         //    AN ERROR IF NOT. ALSO VERIFYING THAT ALL DESCRIPTORS IN THE LIST
  872.         //    ARE OPENDOC TOKENS.
  873.         if (itemCount == 0)
  874.         {
  875.             PlaceEmptyListIntoReply(reply);
  876.             handledEventRightHere = kODTrue;
  877.         }
  878.         else
  879.         {
  880.             for (ODSLong i = 1; i <= itemCount; i++)
  881.             {
  882.                 THROW_IF_ERROR(AEGetNthDesc(token, i, typeWildCard,
  883.                                             &returnedKeyWord,
  884.                                             &embeddedToken));
  885.     
  886.                 ODOSLToken*    odToken = new ODOSLToken;
  887.                 THROW_IF_NULL(odToken);
  888.                 odToken->InitODOSLToken(ev);
  889.                 THROW_IF_ERROR( AEDescToODDesc(&embeddedToken, odToken ) );
  890.                 AEDisposeDesc(&embeddedToken);
  891.     
  892.                 // SANITY CHECKING
  893.                 if (!_fNameResolver->IsODToken(ev, odToken))
  894.                 {
  895.                     delete odToken;
  896.                     ASSERTM(kODFalse, errAEEventNotHandled, "ODMessageInterfaceDispatchEventWithToken: Found descriptor that was not an OpenDoc token while handling list.");
  897.                 }
  898.     
  899.                 _fNameResolver->GetContextFromToken(ev, odToken, &thisPart,
  900.                                                     &thisFrame);
  901.                 if (i > 1)
  902.                 {
  903.                     // SANITY CHECKING
  904.                     if (thisPart != prevPart || thisFrame != prevFrame)
  905.                         ASSERTM(kODFalse, errAEEventNotHandled, "ODMessageInterfaceDispatchEventWithToken: Not all tokens of list came from same place.");
  906.                 }
  907.                 prevPart = thisPart;
  908.                 prevFrame = thisFrame;
  909.  
  910.                 ODDeleteObject(odToken);
  911.             }
  912.  
  913.             ODDesc*    userODToken = new ODDesc;
  914.             THROW_IF_NULL(userODToken);
  915.             userODToken->InitODDesc(ev);
  916.             AEDescToODDesc(token, userODToken);
  917.             OSLDisposeToken(token);
  918.             
  919.             _fNameResolver->CreateNewODOSLToken(ev, token, userODToken,
  920.                                                 thisPart, thisFrame);
  921.         }
  922.     }
  923.  
  924.     if (!handledEventRightHere)
  925.     {
  926.         ODPart* contextPart = _fNameResolver->GetPartFromToken(ev, token);
  927.         
  928.         if ( !dpAlreadyToken ) {
  929.             if ( !usingSubjectAttr ) {
  930.                 THROW_IF_ERROR(AEPutParamDesc(message,
  931.                                             keyDirectObject,
  932.                                             token));
  933.             }
  934.             else {
  935.                 THROW_IF_ERROR(AEPutAttributeDesc(message,
  936.                                             keySubjectAttr,
  937.                                             token));
  938.             }
  939.         }
  940.  
  941.         error =  somSelf->DispatchToEventHandler(ev, message, reply,
  942.                 contextPart, token);
  943.     }
  944.  
  945.     return error;
  946. }
  947.  
  948. //------------------------------------------------------------------------------
  949. // PlaceEmptyListIntoReply
  950. //
  951. //    Place an empty AE list into a reply as the direct parameter.
  952. //------------------------------------------------------------------------------
  953.  
  954. static void PlaceEmptyListIntoReply(AppleEvent* reply)
  955. {
  956.     AEDesc            emptyList;
  957.     const Boolean    kCreateListNotRecord = kODFalse;
  958.  
  959.     THROW_IF_ERROR(AECreateList(kODNULL, 0, kCreateListNotRecord, &emptyList));
  960.     THROW_IF_ERROR(AEPutParamDesc(reply, keyDirectObject, &emptyList));
  961.     AEDisposeDesc(&emptyList);
  962. }
  963.  
  964. #if 0
  965. //------------------------------------------------------------------------------
  966. // ODMessageInterface::HandleSpecialEvents
  967. //
  968. //    Special case some events, like recording events, etc.
  969. //    Return kODTrue if handled the event, kODFalse, if not.
  970. //
  971. //    Since it's a private method, I'm not using SOM exceptions for now.
  972. //------------------------------------------------------------------------------
  973.  
  974. SOM_Scope ODBoolean  SOMLINK ODMessageInterfaceHandleSpecialEvents(ODMessageInterface *somSelf, Environment *ev,
  975.         AppleEvent* message,
  976.         AppleEvent* reply,
  977.         OSErr* error)
  978. {
  979.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  980.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceHandleSpecialEvents");
  981.  
  982.     ODUnused(reply);
  983.  
  984.     ODBoolean    result = kODFalse;
  985.     DescType    eventClass;
  986.     DescType    eventID;
  987.     DescType    actualType;
  988.     Size        maxSize = sizeof(DescType);
  989.     Size        actualSize;
  990.  
  991.     *error = noErr;
  992.     *error = AEGetAttributePtr(message, keyEventClassAttr,
  993.                                 typeType, &actualType, (Ptr)&eventClass,
  994.                                 maxSize, &actualSize);
  995.     if (error || actualType != typeType || actualSize != maxSize)
  996.         return result;
  997.     *error = AEGetAttributePtr(message, keyEventIDAttr,
  998.                                 typeType, &actualType, (Ptr)&eventID, maxSize,
  999.                                 &actualSize);
  1000.     if (error || actualType != typeType || actualSize != maxSize)
  1001.         return result;
  1002.  
  1003.     switch (eventClass)
  1004.     {
  1005.         case kCoreEventClass:
  1006.             switch (eventID)
  1007.             {
  1008.                 // SEND THESE TO ALL RUNNING PARTS THAT HAVE A HANDLER FOR THIS
  1009.                 case kAENotifyStartRecording:
  1010.                     result = kODTrue;
  1011.                     break;
  1012.                 case kAENotifyStopRecording:
  1013.                     result = kODTrue;
  1014.                     break;
  1015.             }
  1016.             break;
  1017.         case kOSASuite:
  1018.             switch (eventID)
  1019.             {
  1020.                 // SEND THESE TO ALL RUNNING PARTS THAT HAVE A HANDLER FOR THIS
  1021.                 case kOSARecordedText:
  1022.                     result = kODTrue;
  1023.                     break;
  1024.             }
  1025.             break;
  1026.     }
  1027.     
  1028.     return result;
  1029. }
  1030. #endif /* 0 */
  1031. //------------------------------------------------------------------------------
  1032. // ODMessageInterface::DispatchToEventHandler
  1033. //
  1034. //    Since it's a private method, I'm not using SOM exceptions for now.
  1035. //------------------------------------------------------------------------------
  1036.  
  1037. SOM_Scope OSErr  SOMLINK ODMessageInterfaceDispatchToEventHandler(ODMessageInterface *somSelf, Environment *ev,
  1038.         AppleEvent* message,
  1039.         AppleEvent* reply,
  1040.         ODPart* contextPart,
  1041.         AEDesc* realToken )
  1042. {
  1043.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1044.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceDispatchToEventHandler");
  1045.  
  1046. //    FN_CATCH return (OSErr)ErrorCode();        // Not SOM_CATCH: we don't want to set ev!
  1047.  
  1048.     // * SET THE CURRENT CONTEXT SO THAT COERCIONS ARE HANDLED CORRECTLY
  1049.     ODPart* savedPart = _fNameResolver->GetCurrentContextPart(ev);
  1050.     _fNameResolver->SetCurrentContextPart(ev, contextPart);
  1051.  
  1052.     // <eeh> optimization note: calling GetTokenPart in the recursive case
  1053.     // is stupid since the result will always be the same as before.  It
  1054.     // would be better to pass the ODPart* itself.  But no time now.
  1055.     // On later consideration, I don't think this makes sense.  The recursive
  1056.     // case is fairly rare and I don't think it's worth the extra calls to
  1057.     // pass in default values (or null) from the other places DispatchToEventHandler
  1058.     // is called just to avoid this one.  Plus there's no way to avoid adding
  1059.     // another parameter to this method.
  1060.  
  1061.     ODPart* partFromStdToken = GetTokenPart( ev, _fNameResolver, realToken );
  1062.     LOG("!DispatchToEventHandler - savedPart %8.8x, contextPart: %8.8x, partFromStdToken: %8.8x\n", 
  1063.             savedPart, contextPart, partFromStdToken);
  1064.     ODBoolean tokenFromDefault
  1065.             = realToken? _fNameResolver->TokenIsDefault(ev, realToken):kODFalse;
  1066.     OSErr result = somSelf->DispatchToEventHandlerAux(ev, message, reply,
  1067.             contextPart, tokenFromDefault, partFromStdToken!=kODNULL );
  1068.  
  1069.     // If we got back errAEEventNotHandled, two things could be wrong in
  1070.     // addition to the usual case where the part that should have gotten
  1071.     // the event got it and couldn't handle it.  One possibility is that
  1072.     // the event should have gone to the root part but went to the shell,
  1073.     // which barfed.  This will happen when there's no direct parameter,
  1074.     // and hence no resolution (with swapping) has taken place.  So we
  1075.     // give the root part a chance.  The second possibility is that the
  1076.     // event should have gone to an embedded part (eg.: tell part 1 to
  1077.     // play part 1) but went to the container, which couldn't handle it.
  1078.     // In this case we should swap to the embedded part so it can try.
  1079.     // Note that *both* can happen in the course of handling the same
  1080.     // event, so we can get three levels of recursion.  Actually, if the
  1081.     // embedded part fails to handle the event we'll almost get a fourth,
  1082.     // but the swapPart != contextPart test will stop the process.
  1083.  
  1084.     if ( result == errAEEventNotHandled )
  1085.     {
  1086.         TempODPart swapPart = kODNULL;
  1087.         if ( contextPart == kODAppShell )
  1088.         {
  1089.             ODFrame* frame = GetDefaultRootFrame(ev, _fSession);
  1090.             if ( frame )
  1091.                 swapPart = frame->AcquirePart(ev);
  1092.         }
  1093.         else        // this may fail, ie return null, which means don't recurse
  1094.         {
  1095.             if ( (swapPart = partFromStdToken) != kODNULL )
  1096.                 swapPart->Acquire( ev );
  1097.         }
  1098.         if ( swapPart )
  1099.         {
  1100.             if ( !ODObjectsAreEqual(ev, swapPart, contextPart) )
  1101.                 result = somSelf->DispatchToEventHandler( ev, message, reply,
  1102.                         swapPart, realToken );
  1103. //            ODReleaseObject( ev, swapPart );
  1104.         }
  1105.     }
  1106.  
  1107.     // * CAN RESTORE CONTEXT NOW.
  1108.     _fNameResolver->SetCurrentContextPart(ev, savedPart);
  1109.     
  1110.     return result;
  1111. }    // DispatchToEventHandler
  1112.  
  1113. //------------------------------------------------------------------------------
  1114. // ODMessageInterface::DispatchToEventHandlerAux
  1115. //
  1116. //    Since it's a private method, I'm not using SOM exceptions for now.
  1117. //------------------------------------------------------------------------------
  1118.  
  1119.  
  1120. SOM_Scope OSErr  SOMLINK ODMessageInterfaceDispatchToEventHandlerAux(ODMessageInterface *somSelf, Environment *ev,
  1121.         AppleEvent* message,
  1122.         AppleEvent* reply,
  1123.         ODPart* sendee,
  1124.         ODBoolean tokenFromDefault,
  1125.         ODBoolean isStdPartToken)
  1126. {
  1127.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1128.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceDispatchToEventHandlerAux");
  1129.  
  1130.     OSErr                    result = noErr;
  1131.     ODSemanticInterface*    si = kODNULL;            ODVolatile(si);
  1132.  
  1133.     ODVolatile(sendee);
  1134.     ODAppleEvent* msgWrapper;                        ODVolatile(msgWrapper);
  1135.     ODAppleEvent* replyWrapper;                        ODVolatile(replyWrapper);
  1136.  
  1137.  
  1138.     TRY
  1139.         msgWrapper = new ODAppleEvent();
  1140.         THROW_IF_NULL(msgWrapper);
  1141.         msgWrapper->InitODAppleEvent(ev);
  1142.         THROW_IF_ERROR( AEDescToODDesc( message, msgWrapper ) );
  1143.  
  1144.         replyWrapper = new ODAppleEvent();
  1145.         THROW_IF_NULL(replyWrapper);
  1146.         replyWrapper->InitODAppleEvent(ev);
  1147.         THROW_IF_ERROR( AEDescToODDesc( reply, replyWrapper ) );
  1148.  
  1149.         TRY
  1150.             si = _fNameResolver->AcquireSemtIntf(ev, sendee);
  1151.             if (si && (!tokenFromDefault || isStdPartToken ))
  1152.                 si->CallEventHandler(ev, sendee, msgWrapper, replyWrapper);
  1153.             else
  1154.                 result = errAEEventNotHandled;
  1155.         CATCH_ALL
  1156.             result = ErrorCode();
  1157.         ENDTRY
  1158.         
  1159.         if (result == errAEEventNotHandled)    // shell doesn't have default accessors! NP - Huh? 6/21/95
  1160.         {
  1161.             TRY
  1162.                 _fDefaultSI->CallEventHandler(ev, sendee, msgWrapper,
  1163.                                                 replyWrapper);
  1164.                 result = noErr;
  1165.             CATCH_ALL
  1166.                 result = ErrorCode();
  1167.             ENDTRY
  1168.         }
  1169.     CATCH_ALL
  1170.         result = ErrorCode();
  1171.     ENDTRY
  1172.  
  1173.     ODReleaseObject(ev,si);
  1174.  
  1175.     ODDeleteObject(msgWrapper);
  1176.  
  1177.     // THE AE MANAGER REALLY WANTS US TO USE THE REPLY DESCRIPTOR THAT IT
  1178.     //    ALLOCATED. SO WE MUST BLOCKMOVE OUR DATA BACK IN.
  1179.  
  1180.     if (reply->descriptorType != typeNull && reply->dataHandle != kODNULL)
  1181.     {
  1182.         // This code overwrites whatever in the header tells the AEM that
  1183.         // this is a valid reply.  Execute this code and the AEM will dispose
  1184.         // the reply before returning from AESend -- in the send-to-self
  1185.         // case, that is. <eeh>
  1186.  
  1187.         ODByteArray data = replyWrapper->GetRawData(ev);
  1188.         SetHandleSize(reply->dataHandle, data._length);
  1189.         THROW_IF_ERROR(MemError());
  1190.         ODBlockMove(data._buffer, *(reply->dataHandle), data._length);
  1191.         DisposeByteArrayStruct(data);
  1192.     }
  1193.  
  1194.     ODDeleteObject(replyWrapper);
  1195.  
  1196.     return result;
  1197. }
  1198.  
  1199. //------------------------------------------------------------------------------
  1200. // HandleReplies
  1201. //------------------------------------------------------------------------------
  1202.  
  1203. static pascal OSErr HandleReplies(AppleEvent* message,
  1204.                                                         AppleEvent* reply,
  1205.                                                         long refCon)
  1206. {
  1207.     ODMessageInterface* self = (ODMessageInterface*)refCon;
  1208.     OSErr result = noErr ;
  1209.  
  1210.     TRY
  1211.         result = self->HandleRepliesAux(somGetGlobalEnvironment(),
  1212.                                         message,
  1213.                                         reply);
  1214.     CATCH_ALL
  1215.         result = ErrorCode();
  1216.     ENDTRY
  1217.  
  1218.     return result ;
  1219. }
  1220.  
  1221. //------------------------------------------------------------------------------
  1222. // ODMessageInterface::HandleRepliesAux
  1223. //
  1224. //    Since it's a private method, I'm not using SOM exceptions for now.
  1225. //------------------------------------------------------------------------------
  1226.  
  1227. SOM_Scope OSErr  SOMLINK ODMessageInterfaceHandleRepliesAux(ODMessageInterface *somSelf, Environment *ev,
  1228.         AppleEvent* message,
  1229.         AppleEvent* reply)
  1230. {
  1231.  
  1232.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1233.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceHandleRepliesAux");
  1234.  
  1235.     ODPart*                aPart;
  1236.     ODSShort            returnID;
  1237.  
  1238.     returnID = GetReturnID(message);
  1239.     if (!_fTransactionList->Find(returnID, &aPart))
  1240.         return errAEEventNotHandled;
  1241.     if (aPart == NULL)
  1242.         return errAEEventNotHandled;
  1243.     else
  1244.         return somSelf->DispatchToEventHandler(ev, message, reply, aPart,
  1245.                 kODNULL );
  1246. }
  1247.  
  1248. //------------------------------------------------------------------------------
  1249. // HandleAllCoercions
  1250. //------------------------------------------------------------------------------
  1251.  
  1252. static OSErr pascal HandleAllCoercions(const AEDesc* theAEDesc,
  1253.                                         DescType    toType,
  1254.                                         long        refCon,
  1255.                                         AEDesc*        retDesc)
  1256. {
  1257.     ODMessageInterface* self = (ODMessageInterface*)refCon;
  1258.     return self->HandleAllCoercionsAux(somGetGlobalEnvironment(),
  1259.                                         (AEDesc*)theAEDesc,
  1260.                                         toType, retDesc);
  1261. }
  1262.  
  1263. //------------------------------------------------------------------------------
  1264. // ODMessageInterface::HandleAllCoercionsAux
  1265. //
  1266. //    Since it's a private method, I'm not using SOM exceptions for now.
  1267. //------------------------------------------------------------------------------
  1268.  
  1269. SOM_Scope OSErr  SOMLINK ODMessageInterfaceHandleAllCoercionsAux(ODMessageInterface *somSelf, Environment *ev,
  1270.         AEDesc* theAEDesc,
  1271.         ODDescType toType,
  1272.         AEDesc* retDesc)
  1273. {
  1274.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1275.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceHandleAllCoercionsAux");
  1276.  
  1277.     ODPart*    contextPart = _fNameResolver->GetCurrentContextPart(ev);
  1278.  
  1279.     return somSelf->DispatchToCoercionHandler(ev, theAEDesc, toType,
  1280.                                                 contextPart, retDesc);
  1281. }
  1282. #if 0
  1283. #endif /* 0 */
  1284. //------------------------------------------------------------------------------
  1285. // ODMessageInterface::DispatchToCoercionHandler
  1286. //
  1287. //    Since it's a private method, I'm not using SOM exceptions for now.
  1288. //------------------------------------------------------------------------------
  1289.  
  1290. SOM_Scope OSErr  SOMLINK ODMessageInterfaceDispatchToCoercionHandler(ODMessageInterface *somSelf, Environment *ev,
  1291.         AEDesc* theAEDesc,
  1292.         ODDescType toType,
  1293.         ODPart* sendee,
  1294.         AEDesc* retDesc)
  1295. {
  1296.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1297.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceDispatchToCoercionHandler");
  1298.  
  1299.     OSErr                    result = noErr;
  1300.     ODSemanticInterface*    si = kODNULL;                ODVolatile(si);
  1301.     
  1302.     TRY
  1303.         si = _fNameResolver->AcquireSemtIntf(ev, sendee);
  1304.         if (si)
  1305.         {
  1306.             ODDesc* realInDesc = new ODDesc();
  1307.             THROW_IF_NULL(realInDesc);
  1308.             realInDesc->InitODDesc(ev);
  1309.             THROW_IF_ERROR( AEDescToODDesc(theAEDesc, realInDesc ) );
  1310.             ODDesc* realOutDesc = new ODDesc();
  1311.             THROW_IF_NULL(realOutDesc);
  1312.             realOutDesc->InitODDesc(ev);
  1313.             // APPLE EVENTS DOESN'T PASS US A NULL DESC APPARENTLY. IT'S FULL
  1314.             //    OF GARBAGE.
  1315.             MakeNULLDesc(retDesc);
  1316.             THROW_IF_ERROR( AEDescToODDesc(retDesc, realOutDesc ) );
  1317.  
  1318.             TRY
  1319.                 si->CallCoercionHandler(ev, sendee, realInDesc, toType, realOutDesc);
  1320.                 THROW_IF_ERROR(ODDescToAEDesc(realOutDesc, retDesc));
  1321.             CATCH_ALL
  1322.                 result = ErrorCode();
  1323.             ENDTRY
  1324.  
  1325.             ODDeleteObject(realInDesc);
  1326.             ODDeleteObject(realOutDesc);
  1327.         }
  1328.         else
  1329.             result = errAECoercionFail;
  1330.     CATCH_ALL
  1331.         result = ErrorCode();
  1332.     ENDTRY
  1333.  
  1334.     ODReleaseObject(ev,si);
  1335.     return result;
  1336. }
  1337.  
  1338. //------------------------------------------------------------------------------
  1339. // HandlePreDispatch
  1340. //
  1341. //    Allow all pre-dispatch procs to look at it. Return noErr IF ANY ONE OF THEM
  1342. //    said they handled it.
  1343. //------------------------------------------------------------------------------
  1344.  
  1345. static OSErr pascal HandlePreDispatch(AppleEvent* message,
  1346.                                                         AppleEvent* reply,
  1347.                                                         long refCon)
  1348. {
  1349.     ODUnused(refCon);
  1350.  
  1351.     OSErr            error = errAEEventNotHandled;
  1352.     ODBoolean        someoneHandled = kODFalse;
  1353.     Environment*    ev = somGetGlobalEnvironment();
  1354.  
  1355.     ODMessageInterface*    msgIntf = gMessageInterface;
  1356.  
  1357.     OrderedCollectionIterator    iter(msgIntf->GetPreHandlers(ev));
  1358.     PreHandlerInfo*                element;
  1359.  
  1360.     TRY
  1361.         for (element = (PreHandlerInfo*)iter.First();
  1362.                 iter.IsNotComplete();
  1363.                 element = (PreHandlerInfo*)iter.Next())
  1364.         {
  1365.             ODAppleEvent* coverEvent = new ODAppleEvent();
  1366.             THROW_IF_NULL(coverEvent);
  1367.             coverEvent->InitODAppleEvent(ev);
  1368.             THROW_IF_ERROR( AEDescToODDesc(message, coverEvent ) );
  1369.             ODAppleEvent* coverReply = new ODAppleEvent();
  1370.             THROW_IF_NULL(coverReply);
  1371.             coverReply->InitODAppleEvent(ev);
  1372.             THROW_IF_ERROR( AEDescToODDesc(reply, coverReply ) );
  1373.  
  1374.             TRY
  1375.                 element->GetSemanticInterface()->CallPredispatchProc(ev,
  1376.                                                                     kODNULL,
  1377.                                                                     coverEvent,
  1378.                                                                     coverReply);
  1379.             CATCH_ALL
  1380.                 error = ErrorCode();
  1381.             ENDTRY
  1382.  
  1383.             if (error == noErr)
  1384.                 someoneHandled = kODTrue;
  1385.  
  1386.             ODDeleteObject(coverEvent);
  1387.             ODDeleteObject(coverReply);
  1388.         }
  1389.     CATCH_ALL
  1390.         error = ErrorCode();
  1391.     ENDTRY
  1392.  
  1393.     if (someoneHandled)
  1394.         return noErr;
  1395.     else
  1396.         return error;
  1397. }
  1398.  
  1399. //------------------------------------------------------------------------------
  1400. // ODMessageInterface::GetPreHandlers
  1401. //------------------------------------------------------------------------------
  1402.  
  1403. SOM_Scope OrderedCollection*  SOMLINK ODMessageInterfaceGetPreHandlers(ODMessageInterface *somSelf, Environment *ev)
  1404. {
  1405.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1406.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceGetPreHandlers");
  1407.  
  1408.     return _fPreHandlers;
  1409. }
  1410.  
  1411. //------------------------------------------------------------------------------
  1412. // ODMessageInterface::GetDefaultSI
  1413. //------------------------------------------------------------------------------
  1414.  
  1415. SOM_Scope ODSemanticInterface*  SOMLINK ODMessageInterfaceGetDefaultSI(ODMessageInterface *somSelf, Environment *ev)
  1416. {
  1417.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1418.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceGetDefaultSI");
  1419.  
  1420.     return _fDefaultSI;
  1421. }
  1422.  
  1423. //------------------------------------------------------------------------------
  1424. // ODMessageInterface::PreHandlerAdded
  1425. //------------------------------------------------------------------------------
  1426.  
  1427. SOM_Scope void  SOMLINK ODMessageInterfacePreHandlerAdded(ODMessageInterface *somSelf, Environment *ev,
  1428.         ODSemanticInterface* face,
  1429.         ODSLong refCon)
  1430. {
  1431.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1432.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfacePreHandlerAdded");
  1433.  
  1434.     SOM_TRY
  1435.  
  1436.     PreHandlerInfo* info = new PreHandlerInfo(face, refCon);
  1437.     _fPreHandlers->AddFirst((ElementType)info);
  1438.     face->Acquire(ev);
  1439.  
  1440.     SOM_CATCH_ALL
  1441.     SOM_ENDTRY
  1442. }
  1443.  
  1444. //------------------------------------------------------------------------------
  1445. // ODMessageInterface::PreHandlerRemoved
  1446. //------------------------------------------------------------------------------
  1447.  
  1448. SOM_Scope void  SOMLINK ODMessageInterfacePreHandlerRemoved(ODMessageInterface *somSelf, Environment *ev,
  1449.         ODSemanticInterface* face,
  1450.         ODSLong refCon)
  1451. {
  1452.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1453.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfacePreHandlerRemoved");
  1454.  
  1455.     OrderedCollectionIterator    iter(somSelf->GetPreHandlers(ev));
  1456.     PreHandlerInfo*                element;
  1457.     ElementType                    elementToRemove = kODNULL;
  1458.  
  1459.     for (element = (PreHandlerInfo*)iter.First();
  1460.             iter.IsNotComplete();
  1461.             element = (PreHandlerInfo*)iter.Next())
  1462.     {
  1463.         if (element->GetSemanticInterface() == face
  1464.                 && element->GetRefCon() == refCon)
  1465.             elementToRemove = element;
  1466.     }
  1467.     if (elementToRemove) {
  1468.         _fPreHandlers->Remove(elementToRemove);
  1469.         ODReleaseObject(ev, face);
  1470.     }
  1471. }
  1472.  
  1473. //------------------------------------------------------------------------------
  1474. // ODMessageInterface::CreatePartAddrDesc
  1475. //------------------------------------------------------------------------------
  1476.  
  1477. SOM_Scope void  SOMLINK ODMessageInterfaceCreatePartAddrDesc(ODMessageInterface *somSelf, Environment *ev,
  1478.         ODAddressDesc** theAddressDesc,
  1479.         ODPart* part)
  1480. {
  1481. //    ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1482.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceCreatePartAddrDesc");
  1483.  
  1484.     ODUnused(part);
  1485.  
  1486.     ProcessSerialNumber PSN;
  1487.     OSErr                result;
  1488.     AEDesc        addressDesc; ODVolatile(addressDesc);
  1489.  
  1490.     SOM_TRY
  1491.         PSN.highLongOfPSN = 0;
  1492.         PSN.lowLongOfPSN = kCurrentProcess;
  1493.         result = AECreateDesc( typeProcessSerialNumber, (Ptr)&PSN, sizeof(PSN), 
  1494.                                 &addressDesc );
  1495.         if ( !result )
  1496.         {
  1497.             ODAddressDesc* newODAddress = new ODAddressDesc();
  1498.             THROW_IF_NULL(newODAddress);
  1499.             newODAddress->InitODAddressDesc(ev);
  1500.             result = AEDescToODDesc( &addressDesc, newODAddress);
  1501.             AEDisposeDesc(&addressDesc);
  1502.             if (!result)
  1503.                 *theAddressDesc = newODAddress;
  1504.             else
  1505.                 *theAddressDesc = kODNULL;
  1506.         }
  1507.     
  1508.         THROW_IF_ERROR (result);
  1509.     SOM_CATCH_ALL
  1510.         *theAddressDesc = kODNULL;
  1511.     SOM_ENDTRY
  1512. }
  1513.  
  1514. //------------------------------------------------------------------------------
  1515. // ODMessageInterface::CreatePartObjSpec
  1516. //------------------------------------------------------------------------------
  1517.  
  1518. SOM_Scope void  SOMLINK ODMessageInterfaceCreatePartObjSpec(ODMessageInterface *somSelf, Environment *ev,
  1519.         ODObjectSpec** theObjSpec,
  1520.         ODPart* thePart)
  1521. {
  1522.  
  1523. //    ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1524.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceCreatePartObjSpec");
  1525.  
  1526.     const Boolean        kDisposeInputs = kODTrue;
  1527.     AEDesc                keyData;
  1528.     AEDesc                nullDesc = NULL_DESCRIPTOR_DEFINITION;
  1529.     AEDesc        newObjSpec; ODVolatile(newObjSpec);
  1530.  
  1531.     SOM_TRY
  1532.         THROW_IF_ERROR(AECreateDesc(typeLongInteger, &thePart, sizeof(long),
  1533.                                 &keyData));
  1534.         // USE cPart as the keyform.
  1535.         THROW_IF_ERROR(CreateObjSpecifier(cPart, &nullDesc, cPart, &keyData,
  1536.                                             kDisposeInputs, &newObjSpec));
  1537.         ODObjectSpec* newODObjSpec = new ODObjectSpec();
  1538.         THROW_IF_NULL(newODObjSpec);
  1539.         newODObjSpec->InitODObjectSpec(ev);
  1540.         THROW_IF_ERROR( AEDescToODDesc(&newObjSpec, newODObjSpec ) );
  1541.         AEDisposeDesc(&newObjSpec);
  1542.         *theObjSpec = newODObjSpec;
  1543.     SOM_CATCH_ALL
  1544.         *theObjSpec = kODNULL;
  1545.     SOM_ENDTRY
  1546. }
  1547.  
  1548. //------------------------------------------------------------------------------
  1549. // ODMessageInterface::InstallDefaultHandlers
  1550. //------------------------------------------------------------------------------
  1551.  
  1552. SOM_Scope void  SOMLINK ODMessageInterfaceInstallDefaultHandlers(ODMessageInterface *somSelf, Environment *ev)
  1553. {
  1554.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1555.     ODMessageInterfaceMethodDebug("ODMessageInterface","ODMessageInterfaceInstallDefaultHandlers");
  1556.  
  1557.     
  1558. }
  1559.  
  1560. #ifdef TO_BE_DELETED
  1561. //------------------------------------------------------------------------------
  1562. // ODMessageInterface: HandleGDUT
  1563. //------------------------------------------------------------------------------
  1564.  
  1565. // <eeh> this reversed the order of enclosed lists.  Shouldn't matter to
  1566. // the current AppleScript, but who knows.
  1567.  
  1568. #define ReturnIfError( funcCall )                                \
  1569.     { OSErr err = (funcCall);                                     \
  1570.     if ( err != noErr ) { return err; } }
  1571.  
  1572. static OSErr AddDPToList( AppleEvent* reply, AEDescList* theList )
  1573. {
  1574.     OSErr err = noErr ;
  1575.     AEDesc item ;
  1576.     ReturnIfError( AEGetKeyDesc( reply, keyDirectObject, typeWildCard, &item ));
  1577.  
  1578.     if ((item.descriptorType == typeAETE) || (item.descriptorType == typeAEUT))
  1579.     {
  1580.         err = AEPutDesc( theList, 0, &item ) ;
  1581.     }
  1582.     else if ( item.descriptorType == typeAEList )
  1583.     {
  1584.         long itemCount ;
  1585.         AECountItems( &item, &itemCount ) ;
  1586.         for( long i = 1; err == noErr && i <= itemCount; ++i )
  1587.         {
  1588.             AEDesc subItem ;
  1589.             DescType ignore ;
  1590.             ReturnIfError( AEGetNthDesc( &item, i, typeWildCard,
  1591.                     &ignore, &subItem ) ) ;
  1592.             err = AddDPToList( &subItem, theList ) ;
  1593.             AEDisposeDesc( &subItem ) ;
  1594.         }
  1595.     }
  1596.     else
  1597.     {
  1598.         WASSERTM( kODFalse, "neither aete nor aeut" ) ;
  1599.     }
  1600.     AEDisposeDesc( &item ) ;
  1601.     return err ;
  1602. }    // AddDPToList()
  1603.  
  1604. SOM_Scope pascal OSErr  SOMLINK ODMessageInterfaceHandleGDUT(ODMessageInterface *somSelf, Environment *ev,
  1605.         AppleEvent* message,
  1606.                                                         AppleEvent* reply,
  1607.                                                         long refCon)
  1608. {
  1609.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1610.     ODMessageInterfaceMethodDebug("ODMessageInterface","HandleGDUT");
  1611.  
  1612.     ODMessageInterface* self = (ODMessageInterface*)refCon;
  1613.     ODMessageInterface* msgInterface = self->_fSession->GetMessageInterface(ev);
  1614.  
  1615.     // Call the shell's GetAETE handler, then iterate through every
  1616.     // part editor getting theirs as well.  Put them all in a list,
  1617.     // making sure the list contains no lists.
  1618.     
  1619.     AEDescList resultList ;
  1620.     ReturnIfError( AECreateList( kODNULL, 0, kODFalse, &resultList ) ) ;
  1621.  
  1622.     ODSemanticInterface* shellSemInt = self->_fSession->GetShellSemtInterface(ev);
  1623.     if ( shellSemInt != kODNULL )
  1624.     {
  1625.         OSErr err = msgInterface->DispatchToEventHandler( message,
  1626.                 reply, kODAppShell ) ;
  1627.         if ( err == noErr )
  1628.             ReturnIfError( AddDPToList( reply, &resultList ) );
  1629.     }
  1630.  
  1631.     
  1632. #ifdef TO_BE_DELETED
  1633.     EditorIterator* ei = self->MakeEditorIterator() ;
  1634.     for( ODSemanticInterface* si = ei->First() ;
  1635.             ie->IsNotComplete() ; si = ei->Next() )
  1636.     {
  1637.         if ( si->HasExtension() && si->IsSemanticEventsExt() )
  1638.         {
  1639.             ReturnIfError( CallGetAETE( si, &oneAETE ) ) ;
  1640.             ReturnIfError( AddDPToList( reply, &resultList ) ) ;
  1641.         }
  1642.     }
  1643. #endif /* TO_BE_DELETED */
  1644.  
  1645.     ReturnIfError( AEPutKeyDesc( reply, keyDirectObject, &resultList ) ) ;
  1646.     AEDisposeDesc( &resultList ) ;
  1647.     return noErr ;
  1648. }    // HandleGDUT()
  1649. #endif /* TO_BE_DELETED */
  1650. //------------------------------------------------------------------------------
  1651. // GetReturnID
  1652. //------------------------------------------------------------------------------
  1653.  
  1654. static ODSShort GetReturnID(AppleEvent* ae)
  1655. {
  1656.     ODSShort    returnID;
  1657.     DescType    actualType;
  1658.     Size        sizeOfBuffer = sizeof(ODSShort);
  1659.     Size        actualSize;
  1660.  
  1661.     THROW_IF_ERROR(AEGetAttributePtr(ae, keyReturnIDAttr,
  1662.                                     typeShortInteger, &actualType,
  1663.                                     (Ptr)&returnID,
  1664.                                     sizeOfBuffer, &actualSize));
  1665.     if ((actualType != typeShortInteger) || (actualSize != sizeOfBuffer))
  1666.         THROW(kODErrOutOfMemory);
  1667.     return returnID;
  1668. }
  1669.  
  1670. //------------------------------------------------------------------------------
  1671. // SentToSelf
  1672. //------------------------------------------------------------------------------
  1673.  
  1674. static ODBoolean SentToSelf(AppleEvent* theAppleEvent)
  1675. {
  1676.     ProcessSerialNumber     PSN;
  1677.     DescType                actualType;
  1678.     Size                    sizeOfBuffer = sizeof(ProcessSerialNumber);
  1679.     Size                    actualSize;
  1680.     Boolean                    isCurrentProcess;
  1681.  
  1682.     THROW_IF_ERROR(AEGetAttributePtr(theAppleEvent,
  1683.                                         keyAddressAttr,
  1684.                                         typeProcessSerialNumber, &actualType,
  1685.                                         (Ptr)&PSN, sizeOfBuffer, &actualSize ));
  1686.     
  1687.     if ((actualType != typeProcessSerialNumber) || (actualSize != sizeOfBuffer))
  1688.         THROW(kODErrOutOfMemory);
  1689.     //$$$$$ THIS IS WRONG. SHOULD BE CALLING SameProcess. AM TOO WORRIED ABOUT
  1690.     //    BREAKING SOMETHING TO FIX IT AT THIS LATE DATE, HOWEVER. -NP 8/30/95
  1691.     isCurrentProcess = ( PSN.lowLongOfPSN == kCurrentProcess );
  1692.     return isCurrentProcess;
  1693. }
  1694.  
  1695. //------------------------------------------------------------------------------
  1696. // GetTokenPart
  1697. // Given a token (of type 'tokn'), determine if the user token it contains
  1698. // is a StandardPartToken and if so return the ODPart* field therefrom.
  1699. // Return NULL in all other cases.
  1700. //------------------------------------------------------------------------------
  1701.  
  1702. static ODPart* GetTokenPart( Environment* ev,
  1703.         ODNameResolver* resolver, AEDesc* realToken )
  1704. {
  1705.     if ( !realToken || (realToken->descriptorType != typeUserToken))
  1706.         return kODNULL;
  1707.  
  1708.     ODPart* result = kODNULL;
  1709.     ODOSLToken* token = new ODOSLToken;
  1710.     THROW_IF_NULL(token);
  1711.     token->InitODOSLToken(ev);
  1712.     if ( AEDescToODDesc( realToken, token ) )
  1713.     {
  1714.         ODDeleteObject(token);
  1715.         return kODNULL;
  1716.     }
  1717.     ODDesc* userToken;
  1718.     userToken = resolver->GetUserToken( ev, token );
  1719.     AEDesc realUserToken;
  1720.     if ( ODDescToAEDesc( userToken, &realUserToken ) )
  1721.         return kODNULL;
  1722.     if ( CanBeStandardPartToken( &realUserToken ) )
  1723.         result = PartFromStandardPartToken( &realUserToken );
  1724.     AEDisposeDesc(&realUserToken);
  1725.     ODDeleteObject(token);
  1726.  
  1727.     return result;
  1728. }
  1729.  
  1730. //------------------------------------------------------------------------------
  1731. // HandleGetAETE
  1732. //------------------------------------------------------------------------------
  1733. pascal OSErr HandleGetAETE(    AppleEvent*    message,
  1734.                             AppleEvent*    reply,
  1735.                             long        refCon)
  1736. {
  1737.     ODMessageInterface *somSelf = (ODMessageInterface*) refCon;
  1738.     ODMessageInterfaceData *somThis = ODMessageInterfaceGetData(somSelf);
  1739.  
  1740.     AEDesc            theAETE = NULL_DESCRIPTOR_DEFINITION;
  1741.     AEDesc            scsz = NULL_DESCRIPTOR_DEFINITION;
  1742.     AEDescList        theList = NULL_DESCRIPTOR_DEFINITION;
  1743.     AppleEvent        realEvent = NULL_DESCRIPTOR_DEFINITION;
  1744.     AppleEvent        realReply = NULL_DESCRIPTOR_DEFINITION;
  1745.     Environment*    ev = somGetGlobalEnvironment();
  1746.     DescType        returnedType;
  1747.     ODSize            actualSize;
  1748.     ODSLong            languageCode;
  1749.     ODAddressDesc*    address;
  1750.     ODAppleEvent*    myEvent;
  1751.     ODAppleEvent*    myReply;
  1752.     OSErr            result;
  1753.     ODSession*        session = _fSession;
  1754.     ODError            error = noErr;
  1755.     ODVolatile(error);
  1756.     
  1757.     TRY
  1758.         result = AEGetParamPtr(message, keyDirectObject, typeLongInteger,
  1759.                                &returnedType, (Ptr)&languageCode, sizeof(languageCode),
  1760.                                (Size *)&actualSize);
  1761.         THROW_IF_ERROR( AECreateList(kODNULL, 0, false, &theList) );
  1762.         
  1763.         // get aete list for all part editors
  1764.         session->GetNameSpaceManager(ev)->GetAETEs(ev, languageCode, &theList);
  1765.         
  1766.         // get aete for shell
  1767.         myReply = new ODAppleEvent();
  1768.         THROW_IF_NULL(myReply);
  1769.         myReply->InitODAppleEvent(ev);
  1770.         TRY
  1771.             somSelf->CreatePartAddrDesc(ev, &address, kODNULL);
  1772.             somSelf->CreateEvent(ev, kAEOpenDocSuite, kGetAETE, address, kAnyTransactionID, &myEvent);
  1773.             THROW_IF_ERROR( ODDescToAEDesc(myEvent, &realEvent) );
  1774.             THROW_IF_ERROR( AEPutParamPtr(&realEvent, keyDirectObject, typeLongInteger, (Ptr) &languageCode, sizeof(languageCode)) );
  1775.             THROW_IF_ERROR( AEDescToODDesc(&realEvent, myEvent) );
  1776.             somSelf->Send(ev, kODNULL, kODNULL, myEvent, myReply, kAEWaitReply+kAEDontRecord, kAENormalPriority, kAEDefaultTimeout);
  1777.             THROW_IF_ERROR( ODDescToAEDesc(myReply, &realReply) );
  1778.             THROW_IF_ERROR( AEGetParamDesc(&realReply, keyAEResult, typeAETE, &theAETE) );
  1779.             THROW_IF_ERROR( AEPutDesc(&theList, 0, &theAETE) );
  1780.         CATCH_ALL
  1781. //            error = ErrorCode();    // we're ignoring this, so we're commented out
  1782.             WARN("Couldn't get shell aete");
  1783.         ENDTRY
  1784.         AEDisposeDesc(&realEvent);
  1785.         AEDisposeDesc(&realReply);
  1786.         AEDisposeDesc(&theAETE);
  1787.         ODDeleteObject(myEvent);
  1788.         ODDeleteObject(myReply);
  1789.         
  1790.         // get aete for OpenDoc from messaging library
  1791.         TRY
  1792.             CUsingLibraryResources    ref;
  1793.             // We pervert the language code because we need two aetes in the single
  1794.             // library version, one for the shell and one for OpenDoc.  This way
  1795.             // container apps can override the shell's aete and provide their own.
  1796.             // The shell aete is numbered normally, but OpenDoc's aetes are numbered
  1797.             // according to this scheme (-1 - languageCode) so that they start at -1
  1798.             // and proceed down from there (as opposed to the normal ones which
  1799.             // start at 0 and proceed upward).
  1800.             theAETE.dataHandle = Get1Resource(typeAETE, (short)(-1-languageCode));
  1801.             THROW_IF_NULL(theAETE.dataHandle);
  1802.             theAETE.descriptorType = typeAETE;
  1803.             result = AEPutDesc(&theList, 0, &theAETE);
  1804.             ReleaseResource(theAETE.dataHandle);
  1805.             THROW_IF_ERROR(result);
  1806.         CATCH_ALL
  1807. //            error = ErrorCode();    // we're ignoring this, so we're commented out
  1808.             WARN("Couldn't get OpenDoc aete");
  1809.         ENDTRY
  1810.         
  1811.         TRY
  1812.             scsz.descriptorType = 'scsz';
  1813.             scsz.dataHandle = Get1Resource('scsz', 0);
  1814.             THROW_IF_NULL(scsz.dataHandle);
  1815.             THROW_IF_ERROR( AEPutParamDesc(reply, keyScszResource, &scsz) );
  1816.         CATCH_ALL
  1817. //            error = ErrorCode();    // we're ignoring this, so we're commented out
  1818.             WARN("Couldn't get OpenDoc scsz");
  1819.         ENDTRY
  1820.  
  1821.         THROW_IF_ERROR( AEPutParamDesc(reply, keyDirectObject, &theList) );
  1822.         THROW_IF_ERROR( AEDisposeDesc(&theList) );
  1823.         
  1824.     CATCH_ALL
  1825.         error = ErrorCode();
  1826.     ENDTRY
  1827.  
  1828.     return error;
  1829. }    // HandleGetAETE()
  1830.  
  1831.  
  1832. void CreateSubjectObject(Environment* ev, ODFrame* frame, AEDesc* objSpec)
  1833. {
  1834.     AEDesc                    nullDesc = NULL_DESCRIPTOR_DEFINITION;
  1835.     AEDesc                    id;
  1836.     ODPersistentObjectID    foo;
  1837.     OSErr                    err;    
  1838.     
  1839.     ODStorageUnit* su = frame->GetStorageUnit(ev);
  1840.     WASSERT(su);
  1841.     ODDraft* draft = su->GetDraft(ev);
  1842.     WASSERT(draft);
  1843.     foo = draft->GetPersistentObjectID( ev, frame, kODFrameObject);
  1844.     THROW_IF_ERROR( AECreateDesc(typeInteger, (Ptr) &foo, sizeof(foo), &id) );
  1845.     err = CreateObjSpecifier(cPart, &nullDesc, formUniqueID, &id, kODFalse, objSpec);
  1846.     AEDisposeDesc(&id);
  1847.     THROW_IF_ERROR(err);
  1848. }    // CreateSubjectObject
  1849.  
  1850.